package run.siyuan.springboot;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor;
import org.springframework.scheduling.config.CronTask;
import org.springframework.scheduling.config.ScheduledTask;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.lang.reflect.Field;
import java.util.Set;

/**
 * @className: SYSpringBootApplication
 * @Description: TODO
 * @author: siyuan
 * @date: 2022/4/27 2:58 PM
 */
@Slf4j
@RestController
@EnableScheduling
@SpringBootApplication
public class SYSpringBootApplication {

    @Autowired
    private ScheduledAnnotationBeanPostProcessor scheduledAnnotationBeanPostProcessor;

    public static void main(String[] args) {
        SpringApplication.run(SYSpringBootApplication.class, args);
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void schedulingMessage1() {
        log.info("时间：{} 打印的日志,Method Name：{}", DateUtil.formatDateTime(DateUtil.date()), "schedulingMessage1");
    }

    @Scheduled(cron = "0/5 * * * * ?")
    public void schedulingMessage2() {
        log.info("时间：{} 打印的日志,Method Name：{}", DateUtil.formatDateTime(DateUtil.date()), "schedulingMessage2");
    }

    @GetMapping("/cancelTask")
    public Object cancelTask(String methodFullName) {
        Set<ScheduledTask> tasks = scheduledAnnotationBeanPostProcessor.getScheduledTasks();
        for (ScheduledTask task : tasks) {
            if (task.getTask().getRunnable().toString().equals(methodFullName)) {
                task.cancel();
            }
        }
        return "success";
    }

    @GetMapping("/updateTask")
    public String updateTask(@RequestBody JSONObject json) throws NoSuchFieldException, IllegalAccessException {
        String cron = json.getStr("cron");
        String methodFullName = json.getStr("methodFullName");
        Field registrar = scheduledAnnotationBeanPostProcessor.getClass().getDeclaredField("registrar");
        registrar.setAccessible(true);
        ScheduledTaskRegistrar taskRegistrar = (ScheduledTaskRegistrar)registrar.get(scheduledAnnotationBeanPostProcessor);
        TaskScheduler scheduler = taskRegistrar.getScheduler();
        Set<ScheduledTask> scheduledTaskSet = scheduledAnnotationBeanPostProcessor.getScheduledTasks();

        for (ScheduledTask task : scheduledTaskSet){
            if (task.getTask().getRunnable().toString().equals(methodFullName)){
                task.cancel();
                CronTask cronTask = new CronTask(task.getTask().getRunnable(), cron);

                scheduler.schedule(cronTask.getRunnable(), cronTask.getTrigger());
            }
        }
        return "success";
    }

}
